﻿using DataCollection.Manage.ProtocalType;
using RQX.Common.Core.Extension;
using RQX.Common.Core.File;
using RQX.Common.Core.Hardware.BaseCollection;
using RQX.Common.Core.Hardware.Com;
using RQX.Common.Core.Model;
using System;
using System.Data;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace DataCollection.Manage
{
    public partial class DeviceEdit : Form
    {
        private readonly string _guid;
        #region Init
        public DeviceEdit(string guid)
        {
            _guid = guid;
            InitializeComponent();
            rbtn_com.Checked = true;
            FormUtils.BindListItemToDDL(ddl_com_portname, ComUtils.GetComList());
            FormUtils.BindListItemToDDL(ddl_com_baudrate, ComUtils.GetBaudRateList());
            FormUtils.BindListItemToDDL(ddl_com_parity, ComUtils.GetParityList());
            FormUtils.BindListItemToDDL(ddl_com_databits, ComUtils.GetDataBitsList());
            FormUtils.BindListItemToDDL(ddl_com_stopbits, ComUtils.GetStopBitsList());
        }
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeviceEdit_Load(object sender, EventArgs e)
        {
            var plugDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            //加载插件列表
            var list = FileUtils.GetAllFiles(plugDirPath, typeof(IIocCollection));
            var source = list.Select(k => new ListItem(k.FullName, k.Name)).ToList();
            FormUtils.BindListItemToDDL(ddl_plug, source);
            if (ddl_plug.Items.Count > 0)
            {
                ddl_plug.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("没有找到可用的插件！");
                return;
            }

            var info = DeviceInfo.list.Find(k => k.GUID.Equals(_guid));
            if (info != null)
            {
                txt_device_name.Text = info.DeviceName;
                var item = ddl_plug.Items.OfType<ListItem>().Find(k => k.Text.Equals(info.PlugName));
                ddl_plug.SelectedIndex = item.IsNull() ? 0 : ddl_plug.Items.IndexOf(item);
                switch (info.ProType)
                {
                    case ProType.UDP:
                        rbtn_udp.Checked = true;
                        txt_udp_target_ip.Text = info.UDP.TargetIP;
                        txt_udp_target_port.Text = info.UDP.TargetPort.ToString();
                        txt_udp_local_port.Text = info.UDP.LocalPort.ToString();
                        break;
                    case ProType.TCPClient:
                        rbtn_tcp_client.Checked = true;
                        txt_tcp_client_ip.Text = info.TCPClient.TargetIP;
                        txt_tcp_client_port.Text = info.TCPClient.TargetPort.ToString();
                        break;
                    case ProType.TCPServer:
                        rbtn_tcp_server.Checked = true;
                        txt_tcp_server_ip.Text = info.TCPServer.LocalIP;
                        txt_tcp_server_port.Text = info.TCPServer.ListenPort.ToString();
                        break;
                    case ProType.COM:
                        rbtn_com.Checked = true;
                        ddl_com_portname.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_portname, info.COM.PortName);
                        ddl_com_baudrate.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_baudrate, info.COM.BaudRate);
                        ddl_com_databits.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_databits, info.COM.DataBits);
                        ddl_com_stopbits.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_stopbits, info.COM.StopBits);
                        ddl_com_parity.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_parity, info.COM.Parity);
                        ckb_com_dtr.Checked = info.COM.DTR;
                        ckb_com_rts.Checked = info.COM.RTS;
                        break;
                }
            }
        }
        #endregion

        #region 选择联动
        /// <summary>
        /// 通讯协议类型选择联动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rbtn_CheckedChanged(object sender, EventArgs e)
        {
            var text = ((RadioButton)sender).Text;
            group_com.Visible = false;
            group_udp.Visible = false;
            group_tcp_client.Visible = false;
            group_tcp_server.Visible = false;
            switch (text)
            {
                case "COM": group_com.Visible = true; break;
                case "UDP": group_udp.Visible = true; break;
                case "TCPClient": group_tcp_client.Visible = true; break;
                case "TCPServer": group_tcp_server.Visible = true; break;
            }
        }
        /// <summary>
        /// 采集插件选择联动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ddl_plug_SelectedIndexChanged(object sender, EventArgs e)
        {
            var item = ddl_plug.SelectedItem as ListItem;
            var path = item.Value;
            var assembly = Assembly.LoadFrom(path);
            var types = assembly.GetTypes().Where(type => typeof(IIocCollection).IsAssignableFrom(type));
            if (types.Count() == 0) return;
            var type = types.First();
            var interfaceInstance = (IIocCollection)Activator.CreateInstance(type);
            switch (interfaceInstance.ProType)
            {
                case ProType.UDP:
                    var udpInstance = (AbstractUdpCollection)interfaceInstance;
                    rbtn_udp.Checked = true;
                    txt_udp_target_ip.Text = udpInstance.IP;
                    txt_udp_target_port.Text = udpInstance.Port.ToString();
                    txt_udp_local_port.Text = udpInstance.Port_Local.ToString();
                    break;
                case ProType.TCPClient:
                    var tcpClientInstance = (AbstractTcpClientCollection)interfaceInstance;
                    rbtn_tcp_client.Checked = true;
                    txt_tcp_client_ip.Text = tcpClientInstance.IP;
                    txt_tcp_client_port.Text = tcpClientInstance.Port.ToString();
                    break;
                case ProType.TCPServer:
                    var tcpServerInstance = (AbstractTcpServerCollection)interfaceInstance;
                    rbtn_tcp_server.Checked = true;
                    txt_tcp_server_ip.Text = tcpServerInstance.IP;
                    txt_tcp_server_port.Text = tcpServerInstance.Port.ToString();
                    break;
                case ProType.COM:
                    var comInstance = (AbstractComCollection)interfaceInstance;
                    rbtn_com.Checked = true;
                    ddl_com_baudrate.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_baudrate, comInstance.BaudRate);
                    ddl_com_databits.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_databits, comInstance.DataBits);
                    ddl_com_stopbits.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_stopbits, comInstance.StopBits);
                    ddl_com_parity.SelectedIndex = FormUtils.FindDDLIndex(ddl_com_parity, comInstance.Parity);
                    ckb_com_dtr.Checked = comInstance.DTR;
                    ckb_com_rts.Checked = comInstance.RTS;
                    break;
            }
        }
        #endregion

        #region 按钮事件
        /// <summary>
        /// 取消
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_cancle_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_save_Click(object sender, EventArgs e)
        {
            if (txt_device_name.Text.Trim().IsNullOrEmpty())
            {
                FormUtils.ShowMsg("请填写采集终端名称！");
                return;
            }

            var device = DeviceInfo.GetDevice(_guid);
            device.DeviceName = txt_device_name.Text;
            device.PlugName = (ddl_plug.SelectedItem as ListItem)?.Text;
            device.ProType = rbtn_com.Checked ? ProType.COM : rbtn_tcp_client.Checked ? ProType.TCPClient : rbtn_tcp_server.Checked ? ProType.TCPServer : rbtn_udp.Checked ? ProType.UDP : ProType.TCPClient;
            switch (device.ProType)
            {
                case ProType.UDP:
                    device.UDP = new UDP()
                    {
                        TargetPort = txt_udp_target_port.Text.Trim().TryToInt(),
                        TargetIP = txt_udp_target_ip.Text.Trim(),
                        LocalPort = txt_udp_local_port.Text.Trim().TryToInt()
                    };
                    break;
                case ProType.TCPClient:
                    device.TCPClient = new TCPClient()
                    {
                        TargetIP = txt_tcp_client_ip.Text.Trim(),
                        TargetPort = txt_tcp_client_port.Text.Trim().TryToInt()
                    };
                    break;
                case ProType.TCPServer:
                    device.TCPServer = new TCPServer()
                    {
                        ListenPort = txt_tcp_server_port.Text.Trim().TryToInt(),
                        LocalIP = txt_tcp_server_ip.Text.Trim()
                    };
                    break;
                case ProType.COM:
                    device.COM = new COM()
                    {
                        PortName = (ddl_com_portname.SelectedItem as ListItem).Text.Trim(),
                        BaudRate = (ddl_com_baudrate.SelectedItem as ListItem).Text.Trim().ToInt(),
                        DataBits = (ddl_com_databits.SelectedItem as ListItem).Value.Trim().ToInt(),
                        StopBits = (ddl_com_stopbits.SelectedItem as ListItem).Text.Trim().ToEnum<StopBits>(),
                        Parity = (ddl_com_parity.SelectedItem as ListItem).Text.Trim().ToEnum<Parity>(),
                        DTR = ckb_com_dtr.Checked,
                        RTS = ckb_com_rts.Checked,
                    };
                    break;
            }
            DeviceInfo.Save();
            this.Close();
        }
        #endregion
    }
}
